// @flow
'use strict';

import React from 'react';
import {
  ART,
  LayoutAnimation,
} from 'react-native';

const {
  Shape,
} = ART;

import Morph from 'art/morph/path';

import PropTypes from 'prop-types';


const AnimationDurationMs = 250;

export default class AnimShape extends React.Component {

  static propTypes = {
    color: PropTypes.string,
    d: PropTypes.func,
  }

  constructor(props: Props) {
    super(props);
    this.state = {
      path: '',
    }
  }

  componentWillMount() {
    this.computeNextState(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.computeNextState(nextProps);
  }

  // Animations based on: https://github.com/hswolff/BetterWeather
  computeNextState(nextProps) {

    const graph = this.props.d();

    this.setState({
      path: graph.path,
    });

    //第一次进入，给this.previousGraph 赋值
    if (!this.previousGraph) {
      this.previousGraph = graph;
    }

    //当props改变的时候触发，
    //获取当前的 path，和下一个path
    //取消上一个动画
    if (this.props !== nextProps) {
      const pathFrom = this.previousGraph.path;
      const pathTo = graph.path;

      cancelAnimationFrame(this.animating);
      this.animating = null;

      //用Morph 创建path 的动画效果，然后执行
      this.setState({
        path: Morph.Tween(
          pathFrom,
          pathTo,
        ),
      }, () => {
        // 执行path
        this.animate();
      });

      this.previousGraph = graph;
    }
  }

  count=0;
  animate(start) {

    this.animating = requestAnimationFrame((timestamp) => {//timestamp 表示回调队列被触发的时间
      if (!start) {
        start = timestamp;
      }

      // 一般情况下，上一帧到下一帧的时间为 33 毫秒，
      // 这里设计的250，是一个极限值，看情况设定,最大限度的减少 count 的次数
      const delta = (timestamp - start) / AnimationDurationMs;

      // 当大于1 的时候取消动画，重新确定当前的路线
      if (delta > 1) {
        this.count=1;
        this.animating = null;
        // 当超过极限值的时候，安全设定path
        this.setState({
          path: this.previousGraph.path,
        });

        return;
      }

      this.count++;
      // 执行动画
      this.state.path.tween(delta);

      this.setState(this.state, () => {
        this.animate(start);
      });
    });
  }

  render() {
    const path = this.state.path;
    return (
       <Shape
         d={path}
         stroke={this.props.color}
         fill={this.props.color}
         />
    );
  }
}
